import LogicFlow, { HtmlNodeModel,HtmlNode, type IHtmlNodeProps, type Model } from "@logicflow/core";
import { createApp,h, type App } from "vue";
import approvalNode from "../node/approvalNode.vue";
import ConditionNode from "../node/conditionNode.vue";
import CopyNode from "../node/copyNode.vue";


const nodeMap = {
    approval: approvalNode,
    condition:ConditionNode,
    copy:CopyNode
}

class CustomNodeModel extends HtmlNodeModel {
    node:any
    constructor(data,graphModel){
        super(data,graphModel)
        this.node = data
        this.height = this.node.properties.height
        this.width = this.node.properties.width
        this.text.editable = false
    }
    getOutlineStyle(): LogicFlow.OutlineTheme {
        const style = super.getOutlineStyle()
        // style.stroke = "#576a95"
        return style
    }
    getConnectedTargetRules(): Model.ConnectRule[] {
        const rules:Model.ConnectRule[]= super.getConnectedTargetRules()
        const rule ={
            message:'',
            validate: (sourceNode, targetNode) => {
                switch(targetNode.properties.prop){
                        case 'approval':
                            return [
                                'apply',
                                'approval',
                                'condition',
                                'copy',
                                "start"
                                ].includes(sourceNode.properties.prop)
                        case 'condition':
                            return [
                                'apply',
                                'approval',
                                'condition',
                                'copy',
                                "start"
                                ].includes(sourceNode.properties.prop)
                        case 'apply': 
                            return [
                                'start'
                                ].includes(sourceNode.properties.prop)
                        case 'copy': 
                            return [
                                'apply',
                                'condition',
                                'approval',
                                ].includes(sourceNode.properties.prop)
                        default:
                            return true
                }
            }
        }
        rules.push(rule)
        return rules
    }
}

class CustomNodeView extends HtmlNode {
    isMounted: boolean
    r:any
    app:App
    constructor(props:IHtmlNodeProps){
        super(props)
        const properties = props.model.getProperties()
        const node = nodeMap[properties.prop]
        this.isMounted = false
        this.r = h(node,{properties})
        this.app = createApp({
            render:()=>this.r
        })
    }
    setHtml(rootEl: SVGForeignObjectElement): void {
        if(!this.isMounted){
            this.isMounted = true
            const nodeContainer = document.createElement('div')
            rootEl.appendChild(nodeContainer)
            this.app.mount(nodeContainer)
        }else{
            this.r.component.props.properties = this.props.model.getProperties()
        }
    }
}


export default {
    type: "customNode",
    view: CustomNodeView,
    model: CustomNodeModel
}